<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * Asset Manager
 *
 * Software to automatically manage how assets are delivered on a website
 *
 * @package		Asset Manager
 * @author		Adam Lewis <adam.lewis@bestservedcold.com>
 * @copyright	Copyright (c) 2006 - 2012, Best Served Cold Media Limited.
 * @license		http://bestservedcold.com/license.html
 * @link		http://bestservedcold.com
 * @since		Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * Handler Library
 *
 * The Handler library deals with getting the information in and out of the
 * CDN.
 *
 * @package		Asset Manager
 * @subpackage	Handler
 * @category	Libraries
 * @author  	Adam Lewis <adam.lewis@bestservedcold.com>
 * @since		2012-05-22
 */
class Am_handler {

	/**
	 * CI
	 *
	 * CodeIgniter super object
	 *
	 * @access	private
	 * @var 	object
	 */
	private $CI;

	private $_asset;

	/**
	 * Constructor
	 *
	 * The constructor gets the CodeIgniter super object.
	 *
	 * @access	public
	 * @since	2012-05-25
	 * @return	void
	 */
	public function __construct()
	{
		log_message('debug', '[HANDLER] Class initialized');

		// Set the CI object for use throughout the class
		$this->CI =& get_instance();

		// We'll need this
		$this->CI->load->config('asset_manager', TRUE);
	}

	public function build_new_asset($param, $group)
	{
		// We need a file to play with... If it's not there, cause a fuss.
		if (! file_exists($_SERVER['DOCUMENT_ROOT'].'/'.$param))
		{
			// Log a message and return FALSE
			log_message('error', "[ASSETS HANDLER] The file [$param] doesn't exist in the file system");
			return FALSE;
		}

		// Set the asset variable, enriching it with the information we'll need.
		$this->_asset = $this->enrich_asset($param, $group);
	}

	public function set_existing_asset($asset)
	{
		$this->_asset = $asset;
	}

	/**
	 * Queue or do
	 *
	 * Queues up the file if the config setting is on, otherwise, it processes the file immediately and the browser will
	 * wait until the file is ready before drawing the page.
	 *
	 * @access		public
	 * @since		2012-05-29
	 * @param 		string		$file
	 * @param 		integer		$identifier
	 * @return		boolean
	 */
	public function queue_or_do()
	{
		// Does this asset want optimizing?
		$this->queue_or_do_optimize();

		// Does this asset want CDN'ing?
		$this->queue_or_do_cdn();

		// Now do the db work
		$this->process_asset();

		// Return the asset
		return $this->_asset;
	}

	private function queue_or_do_optimize()
	{
		log_message('error', "I'm not sure I want to optimize");
		// Get our filetype for the naming convention
		$type = $this->get_asset_type($this->_asset['filetype']);

		// Does that type of file want to be optimized
		if ($this->CI->config->item("queue_optimize_$type", 'asset_manager'))
		{
			// Does it need queuing?
			if ($this->CI->config->item("queue_optimize_$type", 'asset_manager'))
			{
				// Load up the handler queue library and queue it
				$this->CI->load->library('asset_manager/am_handler/am_handler_queue');
				$this->CI->am_handler_queue->queue($this->_asset, $type);
			}
			else
			{
				log_message('error', "I want to optimize");
				// Load up the correct library for that filetype and process immediately
				$this->CI->load->library("asset_manager/am_optimize/am_optimize_$type", 'optimize');
				$this->_asset = $this->CI->optimize->process($this->_asset);
			}
		}
	}

	private function queue_or_do_cdn()
	{
		// Are we CDN'ing?
		if ($this->CI->config->item('cdn', 'asset_manager'))
		{
			// Are we queueing or processing?
			if ($this->CI->config->item('queue_cdn', 'asset_manager'))
			{
				$this->CI->load->library('asset_manager/am_handler/am_handler_queue');
				$this->CI->am_handler_queue->queue($this->_asset, 'cdn');
			}
			else
			{
				// Process_immediately
				$provider = 'am_cdn_'.$this->CI->config->item('cdn_host', 'asset_manager');
				$this->CI->load->library("asset_manager/am_cdn/$provider");
				$this->_asset = $this->CI->$provider->put_asset($this->_asset);
			}
		}
	}

	/**
	 * Process Asset
	 *
	 * Processes an individual asset
	 *
	 * @access		protected
	 * @since		2012-05-25
	 * @param 		array			$asset
	 * @return		boolean
	 */
	protected function process_asset()
	{
		// Delete the file from the database, if it exists
		$this->delete_asset_db($this->_asset['file']);

		// And pop it back in with our new details
		$this->CI->db->insert($this->CI->config->item('asset_table', 'asset_manager'), $this->_asset);
	}

	/**
	 * Delete Asset DB
	 *
	 * Deletes the asset from the database
	 *
	 * @access		protected
	 * @since		2012-05-28
	 * @param		string			$file
	 * @return		boolean
	 */
	private function delete_asset_db($file)
	{
		return $this->CI->db->delete($this->CI->config->item('asset_table', 'asset_manager'),
			array('file' => $file));
	}

	/**
	 * Enrich Asset
	 *
	 * Adds more information to the asset for reference later
	 *
	 * @access		private
	 * @since		2012-05-29
	 * @param		string		$file
	 * @param		ingeger		$group
	 * @return		array
	 */
	private function enrich_asset($file, $group = FALSE)
	{
		$this->CI->load->helper('file');
		$asset = array(
			'file' 			=> $file,
			'filesize'		=> floor(filesize($file)/1024),
			'filedate'		=> filemtime($file),
			'filetype'		=> get_mime_by_extension($file)
		);
		$group ? $asset['group'] = $group : NULL;
		return $asset;
	}

	/**
	 * Get Asset Type
	 *
	 * Get's the asset type so we can work out what library to call to get things done
	 *
	 * @access	private
	 * @since	2012-06-13
	 * @param	string	$mimetype
	 * @return	string
	 */
	private function get_asset_type($mimetype)
	{
		foreach (array('image' => 'images', 'css' => 'css', 'js|javascript' => 'js') as $type => $result)
		{
			if (preg_match("/$type/", $mimetype))
			{
				return $type;
			}
		}
	}
}